#include "bspInit.h"

/* Public area */
extern err_t ethernetif_init(struct netif *netif);
extern void  ethernetif_input(struct netif *netif);

__IO static bool flag_1ms = 0, flag_250ms = 0, flag_5000ms = 0;
__IO static uint16_t timeCnt_1ms = 0;
__IO static bool recvPacket = 0;

/* Private area */
#ifdef NIC_ENC28J60
	struct netif netif_enc28j60;
	uint8_t  gENC2860_MAC[] = {'E', 'N', 'C', '2', '8', 'J'};
	#define NICIF netif_enc28j60
	
#elif defined(NIC_KSZ8041NL)
	struct netif netif_ksz8041nl;
//	uint8_t  gKSL8041_MAC[] = {'K', 'S', '8', '0', '4', 'J'};   /* MAC address can not be a multicast address */
	uint8_t  gKSL8041_MAC[] = {0x22, 0x22, 0x22, 0x00, 0x00, 'J'};
	#define NICIF netif_ksz8041nl
#endif
	
void bspInit_DUYA(void)
{
	/* Basic modules initialize */
    GPIO_QuickInit(HW_GPIOE, 6, kGPIO_Mode_OPP);
	UART_QuickInit(UART0_RX_PD06_TX_PD07, 115200);

	/* PIT module initialize */
	PIT_QuickInit(HW_PIT_CH0, 1*1000);
    PIT_CallbackInstall(HW_PIT_CH0, PIT_CH0_ISR); 
    PIT_ITDMAConfig(HW_PIT_CH0, kPIT_IT_TOF,ENABLE); 

#ifdef NIC_ENC28J60
	/* SPI initialization for ENC28J60 */
    SPI_QuickInit(SPI2_SCK_PD12_SOUT_PD13_SIN_PD14, kSPI_CPOL0_CPHA0, 2*1000*1000);
	/* SPI2_PCS0 */
    GPIO_QuickInit(HW_GPIOD, 11, kGPIO_Mode_OPP);
	/* Select pcs0 */
    enc28j60_init(HW_SPI2, HW_SPI_CS0);
	
#elif defined(NIC_KSZ8041NL)
	/* ENET MAC controller initialization */
	/* Initialize KSZ8041NL NIC */
	InitKSZ8041NL();
	/* Init ENET module */
	ENET_InitTypeDef ENET_InitStruct1;
    ENET_InitStruct1.pMacAddress = gKSL8041_MAC;	
    ENET_InitStruct1.is10MSpped = enet_phy_is_10m_speed();
    ENET_InitStruct1.isHalfDuplex = !enet_phy_is_full_dpx();
    ENET_Init(&ENET_InitStruct1);
	ENET_CallbackRxInstall(ENET_ISR);
    ENET_ITDMAConfig(kENET_IT_RXF);
#endif	
	printf("Hello Kinetis!%s\r\n", "Modules initialize successfully!");
}

void netInit(void)
{
#ifdef NIC_ENC28J60
	#if NET_DEBUG_ON
	/* check whether spi comm is ok */
	uint8_t version = 0;
	version = enc28j60getrev();
	printf("version = %d\r\n", version);
	#endif
#endif
	
	/* ifconfig */
	struct ip_addr ipaddr;
	struct ip_addr netmask;
	struct ip_addr gw;
	/* lwip internal initialization func,in order to 
	 * intialize linked list,memory pool and pBuf struct 
	 */
	lwip_init();
	
#if LWIP_DHCP					 
//    ipaddr.addr		= 0;
//    netmask.addr	= 0;
//    gw.addr			= 0;
	IP4_ADDR(&ipaddr,  0, 0, 0, 0);
    IP4_ADDR(&netmask, 0, 0, 0, 0);
    IP4_ADDR(&gw,      0, 0, 0, 0);
#else    
    IP4_ADDR(&ipaddr, 192, 168, 1, 103);
    IP4_ADDR(&netmask, 255, 255, 255, 0);
    IP4_ADDR(&gw, 192, 168, 1, 1);
#endif
	/* initialize the interfaces between nic and lwip */
	netif_add(&NICIF, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);

    /* set enc26j80 as default nic */
	netif_set_default(&NICIF);
	/* When the netif is fully configured this function must be called.*/
    /* Enable ENC28J60 NIC */
	netif_set_up(&NICIF);
		
#ifdef NIC_ENC28J60
	#if NET_DEBUG_ON
	/* printf the mac address of nic */
	printf("%x\r\n", enc28j60Read(MAADR0));
	printf("%x\r\n", enc28j60Read(MAADR1));
	printf("%x\r\n", enc28j60Read(MAADR2));
	printf("%x\r\n", enc28j60Read(MAADR3));
	printf("%x\r\n", enc28j60Read(MAADR4));
	printf("%x\r\n", enc28j60Read(MAADR5));	
	#endif
#endif

	/* DHCP demo */
#if LWIP_DHCP	
    printf("dhcp start getting addr...\r\n");
    err_t result = dhcp_start(&NICIF);
	printf("result = %d\r\n", result);
    while(NICIF.dhcp->offered_ip_addr.addr == 0)
    {
        if( flag_1ms )
        {
            ethernetif_input(&NICIF);
			flag_1ms 	= 0;
        }
    }
    
    dhcp_fine_tmr();
    netif_set_addr(&NICIF, &(NICIF.dhcp->offered_ip_addr), &(NICIF.dhcp->offered_sn_mask), &(NICIF.dhcp->offered_gw_addr));
    netif_set_default(&NICIF);
    netif_set_up(&NICIF);
        
    u8_t *ip = (u8_t*)&NICIF.ip_addr.addr;
    printf("dhcp new ip: %u.%u.%u.%u \r",ip[0], ip[1],ip[2], ip[3]);
#endif
}

/**
 * \brief PIT Interrupt function
 */
void PIT_CH0_ISR(void)
{
	timeCnt_1ms++;
	if((timeCnt_1ms%1) == 0)
		flag_1ms = 1;
	if((timeCnt_1ms%250) == 0)
		flag_250ms = 1;
	if((timeCnt_1ms%5000) == 0)
	{
		flag_5000ms = 1;
		timeCnt_1ms = 0;
	}
}

/**
 * \brief ENET Interrupt Recv function
 */
void ENET_ISR(void)
{
	recvPacket = 1;
}

/**
 * \brief Called periodically to deal with ethernet packets
 */
void LwIP_Periodic_Handle(void)
{
	if( flag_1ms )
	{
#ifdef NIC_KSZ8041NL
	if( recvPacket == 1 )
#endif
	{
		/* receive the ethernet packet */
		ethernetif_input(&NICIF);	
		flag_1ms 	= 0;
		recvPacket 	= 0;
	}
	
	if(flag_250ms)
	{
		/* Called every 250 ms */
		tcp_tmr();	
		/* Led flashing to indicate working status */
		GPIO_ToggleBit(HW_GPIOE, 6);
		flag_250ms = 0;
	}
	
	if(flag_5000ms)
	{
		/* Called every 5000 ms */
		etharp_tmr();
		flag_5000ms = 0;
	}
	}
}
